package com.cango.student.io.bio;

import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
 * BIO服务端源码__伪异步I/O
 * 代码错误，因为阻塞
 * @author yangtao__anxpp.com
 * @version 1.0
 */
public final class ServerBetter {
    //默认的端口号
    private static int DEFAULT_PORT = 12345;
    //单例的ServerSocket
    private static ServerSocket server;
    //线程池 懒汉式的单例
    private static ExecutorService executorService = Executors.newFixedThreadPool(60);
    //根据传入参数设置监听端口，如果没有参数调用以下方法并使用默认值
    public static void start() throws IOException{
        //使用默认值
        start(DEFAULT_PORT);
    }
    //这个方法不会被大量并发访问，不太需要考虑效率，直接进行方法同步就行了
    public synchronized static void start(int port) throws IOException{
        if(server != null) return;
        try{
            //通过构造函数创建ServerSocket
            //如果端口合法且空闲，服务端就监听成功
            server = new ServerSocket(port);
            System.out.println("服务器已启动，端口号：" + port);
            //通过无线循环监听客户端连接
            //如果没有客户端接入，将阻塞在accept操作上。
            while(true){
                Socket socket = server.accept();
                //当有新的客户端接入时，会执行下面的代码
                //然后创建一个新的线程处理这条Socket链路
                executorService.execute(new ServerHandler(socket));
            }
        }finally{
            //一些必要的清理工作
            if(server != null){
                System.out.println("服务器已关闭。");
                server.close();
                server = null;
            }
        }
    }

    // 简化实现，不做读取，直接发送文字
    static class ServerHandler extends Thread {
        private Socket socket;

        ServerHandler(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {

            try (PrintWriter out = new PrintWriter(new BufferedOutputStream(socket.getOutputStream()))) {
                out.print("hello world");
                out.flush();
            } catch (Exception e) {
                e.printStackTrace();
            }

//            try (OutputStream o = socket.getOutputStream()) {
//                o.write(new String("hello world OutputStream").getBytes());
//                o.flush();
//            } catch (Exception e) {
//                e.printStackTrace();
//            }

        }

    }

    public static void main(String[] args) throws IOException {
        ServerBetter.start();
        // 利用socket模拟了一个简单客户端，只进行连接，读取，打印
        try (Socket client = new Socket(InetAddress.getLocalHost(), DEFAULT_PORT)) {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(client.getInputStream()));
            bufferedReader.lines().forEach(s -> System.out.println(s));
        }
    }
}
